
#include "OgreApp.h"

OgreApp::OgreApp() : _keepRunning(true) {
	_sceneManager = NULL;
	_root = NULL;
	_listener = NULL;
	_SinbadNode = NULL;
}
OgreApp::~OgreApp() {
	if(_root) delete _root;
	if(_listener) delete _listener;
}

void OgreApp::createScene() {
		
	Ogre::Plane plane(Ogre::Vector3::UNIT_Y, -5);
	Ogre::MeshManager::getSingleton().createPlane("plane", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, 1500, 1500, 200, 200, true, 1, 5, 5, Ogre::Vector3::UNIT_Z);

	Ogre::Entity* ground = _sceneManager->createEntity("LightPlaneEntity", "plane");
	_sceneManager->getRootSceneNode()->createChildSceneNode()->attachObject(ground);
	ground->setMaterialName("Examples/BeachStones");

	Ogre::Light* light = _sceneManager->createLight("Light1");
	light->setType(Ogre::Light::LT_DIRECTIONAL);
	light->setDirection(Ogre::Vector3(1,-1,0));

	_SinbadEnt = _sceneManager->createEntity("Sinbad.mesh");
	_SinbadNode = _sceneManager->getRootSceneNode()->createChildSceneNode();
	_SinbadNode->attachObject(_SinbadEnt);

	Ogre::ParticleSystem* partSystem1 = _sceneManager->createParticleSystem("Firework1", "Firework");
	Ogre::ParticleSystem* partSystem2 = _sceneManager->createParticleSystem("Firework2", "Firework");
	Ogre::ParticleSystem* partSystem3 = _sceneManager->createParticleSystem("Firework3", "Firework");
	Ogre::ParticleSystem* partSystem4 = _sceneManager->createParticleSystem("Firework4", "Firework");
	Ogre::ParticleSystem* partSystem5 = _sceneManager->createParticleSystem("Firework5", "Firework");
	Ogre::SceneNode* node1 = _sceneManager->getRootSceneNode()->createChildSceneNode(Ogre::Vector3(0, 10, 0));
	Ogre::SceneNode* node2 = _sceneManager->getRootSceneNode()->createChildSceneNode(Ogre::Vector3(10, 11, 0));
	Ogre::SceneNode* node3 = _sceneManager->getRootSceneNode()->createChildSceneNode(Ogre::Vector3(20, 9, 0));
	Ogre::SceneNode* node4 = _sceneManager->getRootSceneNode()->createChildSceneNode(Ogre::Vector3(-10, 11, 0));
	Ogre::SceneNode* node5 = _sceneManager->getRootSceneNode()->createChildSceneNode(Ogre::Vector3(-20, 19, 0));
	node1->attachObject(partSystem1);
	node2->attachObject(partSystem2);
	node3->attachObject(partSystem3);
	node4->attachObject(partSystem4);
	node5->attachObject(partSystem5);

	_sceneManager->setShadowTechnique(Ogre::SHADOWTYPE_STENCIL_ADDITIVE);
}

int OgreApp::startup() {

#if OGRE_DEBUG_MODE
	_root = new Ogre::Root("plugins_d.cfg");
#else
	_root = new Ogre::Root("plugins.cfg");
#endif
	if(!_root->showConfigDialog()) { return -1; }
	
	Ogre::RenderWindow* window = _root->initialise(true, "Ogre3D Beginners Guide");
	_sceneManager = _root->createSceneManager(Ogre::ST_GENERIC);

	Ogre::Camera* camera = _sceneManager->createCamera("Camera");
	camera->setPosition(Ogre::Vector3(0, 0, 50));
	camera->lookAt(Ogre::Vector3(0, 0, 0));
	camera->setNearClipDistance(5);
	
	Ogre::Viewport* viewport = window->addViewport(camera);
	viewport->setBackgroundColour(Ogre::ColourValue(0.0, 0.0, 0.0));

	camera->setAspectRatio(Ogre::Real(viewport->getActualWidth())/Ogre::Real(viewport->getActualHeight()));
	
	loadResources();
	createScene();

	_listener = new OgreFrameListener(window, camera, viewport, _SinbadNode, _SinbadEnt);
	_root->addFrameListener(_listener);

	/*
	Ogre::CompositorManager::getSingleton().addCompositor(viewport, "Compositor2");
	Ogre::CompositorManager::getSingleton().addCompositor(viewport, "Compositor3");
	Ogre::CompositorManager::getSingleton().addCompositor(viewport, "Compositor7");
	*/
	//_root->startRendering();
}

void OgreApp::renderOneFrame() {

	Ogre::WindowEventUtilities::messagePump();
	_keepRunning = _root->renderOneFrame();
}

void OgreApp::loadResources() {

	Ogre::ConfigFile cf;

#if OGRE_DEBUG_MODE
	cf.load("resources_d.cfg");
#else
	cf.load("resources.cfg");
#endif

	Ogre::ConfigFile::SectionIterator sectionIter = cf.getSectionIterator();

	Ogre::String sectionName, typeName, dataName;
	while(sectionIter.hasMoreElements()) {

		sectionName = sectionIter.peekNextKey();
		Ogre::ConfigFile::SettingsMultiMap* settings = sectionIter.getNext();
		Ogre::ConfigFile::SettingsMultiMap::iterator i;
		for(i=settings->begin(); i!=settings->end(); ++i) {

			typeName = i->first;
			dataName = i->second;
			Ogre::ResourceGroupManager::getSingleton().addResourceLocation(dataName, typeName, sectionName);
		}
	}
	Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
}
